From e3fc1d0f8c90e8312ba67541eebde61abab934bf Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Wed, 20 Jun 2018 20:43:53 +0200 Subject: [PATCH] babl: add ~ variants to gray color models We do not add premultiplied sRGB trc variants even if this exists for RGB since it is the type of premultiplied alpha cairo expects. The less code that does non-linear compositing the better, excluding some possibilities also reduces the combinatorial overhead of finding conversion paths in babl. --- babl/babl-ids.h | 9 +-- babl/base/formats.c | 6 +- babl/base/model-gray.c | 154 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 150 insertions(+), 19 deletions(-) diff --git a/babl/babl-ids.h b/babl/babl-ids.h index 324b240..a35efd2 100644 --- a/babl/babl-ids.h +++ b/babl/babl-ids.h @@ -47,10 +47,10 @@ enum { BABL_RGBA_PREMULTIPLIED, BABL_MODEL_GRAY_NONLINEAR, BABL_MODEL_GRAY_NONLINEAR_ALPHA, - BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED, - BABL_GRAY_PERCEPTUAL, - BABL_GRAY_PERCEPTUAL_ALPHA, - BABL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED, + BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED, + BABL_MODEL_GRAY_PERCEPTUAL, + BABL_MODEL_GRAY_PERCEPTUAL_ALPHA, + BABL_MODEL_GRAY_PERCEPTUAL_ALPHA_PREMULTIPLIED, BABL_RGB_NONLINEAR, BABL_RGBA_NONLINEAR, BABL_RGBA_NONLINEAR_PREMULTIPLIED, @@ -73,6 +73,7 @@ enum { BABL_RED_MUL_ALPHA, BABL_GREEN_MUL_ALPHA, BABL_BLUE_MUL_ALPHA, + BABL_GRAY_PERCEPTUAL, BABL_GRAY_NONLINEAR, BABL_GRAY_NONLINEAR_MUL_ALPHA, BABL_RED_NONLINEAR, diff --git a/babl/base/formats.c b/babl/base/formats.c index 97e6e8b..7affcc5 100644 --- a/babl/base/formats.c +++ b/babl/base/formats.c @@ -111,7 +111,7 @@ babl_formats_init (void) babl_component_from_id (BABL_ALPHA), NULL); babl_format_new ( - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), babl_type_from_id (BABL_FLOAT), babl_component_from_id (BABL_GRAY_NONLINEAR_MUL_ALPHA), babl_component_from_id (BABL_ALPHA), @@ -128,7 +128,7 @@ babl_formats_init (void) babl_component_from_id (BABL_ALPHA), NULL); babl_format_new ( - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), babl_type_from_id (BABL_U16), babl_component_from_id (BABL_GRAY_NONLINEAR_MUL_ALPHA), babl_component_from_id (BABL_ALPHA), @@ -145,7 +145,7 @@ babl_formats_init (void) babl_component_from_id (BABL_ALPHA), NULL); babl_format_new ( - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), babl_type_from_id (BABL_U8), babl_component_from_id (BABL_GRAY_NONLINEAR_MUL_ALPHA), babl_component_from_id (BABL_ALPHA), diff --git a/babl/base/model-gray.c b/babl/base/model-gray.c index 47a875b..ea1ca98 100644 --- a/babl/base/model-gray.c +++ b/babl/base/model-gray.c @@ -19,8 +19,7 @@ #include "config.h" #include -#include "babl-classes.h" -#include "babl.h" +#include "babl-internal.h" #include "babl-ids.h" #include "math.h" #include "babl-base.h" @@ -64,6 +63,12 @@ components (void) "id", BABL_GRAY_NONLINEAR_MUL_ALPHA, "luma", NULL); + + babl_component_new ( + "Y~", + "id", BABL_GRAY_PERCEPTUAL, + "luma", + NULL); } static void @@ -87,9 +92,8 @@ models (void) babl_component_from_id (BABL_ALPHA), NULL); - babl_model_new ( - "id", BABL_GRAY_NONLINEAR, + "id", BABL_MODEL_GRAY_NONLINEAR, babl_component_from_id (BABL_GRAY_NONLINEAR), NULL); @@ -100,12 +104,23 @@ models (void) NULL); babl_model_new ( - "id", BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED, + "id", BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED, babl_component_from_id (BABL_GRAY_NONLINEAR_MUL_ALPHA), babl_component_from_id (BABL_ALPHA), NULL); -} + babl_model_new ( + "id", BABL_MODEL_GRAY_PERCEPTUAL, + babl_component_from_id (BABL_GRAY_PERCEPTUAL), + NULL); + + babl_model_new ( + "id", BABL_MODEL_GRAY_PERCEPTUAL_ALPHA, + babl_component_from_id (BABL_GRAY_PERCEPTUAL), + babl_component_from_id (BABL_ALPHA), + NULL); + +} static void rgba_to_graya (Babl *conversion, @@ -171,6 +186,8 @@ rgba_to_gray (Babl *conversion, } } +static const Babl *perceptual_trc = NULL; + static void rgb_to_gray_nonlinear (Babl *conversion, int src_bands, @@ -254,6 +271,88 @@ gray_nonlinear_to_rgb (Babl *conversion, } } +static void +rgb_to_gray_perceptual (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + const Babl *space = babl_conversion_get_destination_space (conversion); + const Babl *trc = perceptual_trc; + double RGB_LUMINANCE_RED = space->space.RGBtoXYZ[3]; + double RGB_LUMINANCE_GREEN = space->space.RGBtoXYZ[4]; + double RGB_LUMINANCE_BLUE = space->space.RGBtoXYZ[5]; + + BABL_PLANAR_SANITY + while (n--) + { + double red, green, blue; + double luminance, alpha; + + red = *(double *) src[0]; + green = *(double *) src[1]; + blue = *(double *) src[2]; + if (src_bands > 3) + alpha = *(double *) src[3]; + else + alpha = 1.0; + + luminance = red * RGB_LUMINANCE_RED + + green * RGB_LUMINANCE_GREEN + + blue * RGB_LUMINANCE_BLUE; + *(double *) dst[0] = babl_trc_from_linear (trc, luminance); + + if (dst_bands == 2) + *(double *) dst[1] = alpha; + + BABL_PLANAR_STEP + } +} + +static void +gray_perceptual_to_rgb (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + const Babl *trc = perceptual_trc; + + BABL_PLANAR_SANITY + while (n--) + { + double luminance; + double red, green, blue; + double alpha; + + luminance = babl_trc_to_linear (trc, *(double *) src[0]); + red = luminance; + green = luminance; + blue = luminance; + if (src_bands > 1) + alpha = *(double *) src[1]; + else + alpha = 1.0; + + *(double *) dst[0] = red; + *(double *) dst[1] = green; + *(double *) dst[2] = blue; + + if (dst_bands > 3) + *(double *) dst[3] = alpha; + + BABL_PLANAR_STEP + } +} + + static void graya_to_rgba (Babl *conversion, char *src, @@ -516,10 +615,10 @@ gray_nonlinear_premultiplied2rgba (Babl *conversion, } } - static void conversions (void) { + perceptual_trc = babl_trc ("sRGB"); babl_conversion_new ( babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR), babl_model_from_id (BABL_RGBA), @@ -550,7 +649,7 @@ conversions (void) babl_conversion_new ( - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), babl_model_from_id (BABL_RGBA), "linear", gray_nonlinear_premultiplied2rgba, NULL @@ -558,11 +657,42 @@ conversions (void) babl_conversion_new ( babl_model_from_id (BABL_RGBA), - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), "linear", rgba2gray_nonlinear_premultiplied, NULL ); + + + babl_conversion_new ( + babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL), + babl_model_from_id (BABL_RGBA), + "planar", gray_perceptual_to_rgb, + NULL + ); + + babl_conversion_new ( + babl_model_from_id (BABL_RGBA), + babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL), + "planar", rgb_to_gray_perceptual, + NULL + ); + + babl_conversion_new ( + babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA), + babl_model_from_id (BABL_RGBA), + "planar", gray_perceptual_to_rgb, + NULL + ); + + babl_conversion_new ( + babl_model_from_id (BABL_RGBA), + babl_model_from_id (BABL_MODEL_GRAY_PERCEPTUAL_ALPHA), + "planar", rgb_to_gray_perceptual, + NULL + ); + + babl_conversion_new ( babl_model_from_id (BABL_GRAY), babl_model_from_id (BABL_RGBA), @@ -647,7 +777,7 @@ formats (void) babl_component_from_id (BABL_ALPHA), NULL); babl_format_new ( - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), babl_type_from_id (BABL_HALF), babl_component_from_id (BABL_GRAY_NONLINEAR_MUL_ALPHA), babl_component_from_id (BABL_ALPHA), @@ -683,7 +813,7 @@ formats (void) babl_component_from_id (BABL_ALPHA), NULL); babl_format_new ( - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), babl_type ("u15"), babl_component_from_id (BABL_GRAY_NONLINEAR_MUL_ALPHA), babl_component_from_id (BABL_ALPHA), @@ -718,7 +848,7 @@ formats (void) babl_component_from_id (BABL_ALPHA), NULL); babl_format_new ( - babl_model_from_id (BABL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), + babl_model_from_id (BABL_MODEL_GRAY_NONLINEAR_ALPHA_PREMULTIPLIED), babl_type_from_id (BABL_U32), babl_component_from_id (BABL_GRAY_NONLINEAR_MUL_ALPHA), babl_component_from_id (BABL_ALPHA), -- 2.30.2